home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 3
/
The Arsenal Files 3.iso
/
gen_prog
/
appdemo.exe
/
STRING.APP
< prev
next >
Wrap
Text File
|
1994-11-07
|
28KB
|
955 lines
// STRING LIBRARY
// ==============
// This file contains the STRING library of functions.
// You can modify it to suit your particular needs. If you
// do then it would be a good idea to lable all your changes with a unique
// string in a comment so that if you get an upgrade you can remake those
// changes.
// MAXSTRUCTURES is the maximum number of structures with strings in them
// that can be current at any one time. It is used by TidyStringHeap()
// to do a garbage collection when the string heap gets full.
#define MAXSTRUCTURES 100
string MidString(BX_String, CX_Start, int Length)
{
// Returns Length characters of BX_String starting from CX_Start
string Dest;
PUSH CX; // Save CX for later
Dest = BX; // Copy to new string
POP CX; // Restore CX again
while(CX_Start > 0) // For each character before CX_Start
{
if(Dest[0] == 0) break; // Stay within bounds of string
Dest[0] = 0; // Clear the first character in Dest
Dest++; // Move the Dest pointer forward
CX--; // One less character to delete
}
BX = Dest; // Point to start of string
CX = BX + Length; // Pointer from where to start deleting
while(S1[BX]) // while not end of string
{
if(BX .>=. CX) // If Position >= CX (Unsigned compare)
{
S1[BX] = 0; // Clear byte
}
BX++; // Increment BX
}
if(Dest[0] == 0) Dest == StringHeapStartAddress + 2; // NULL string
return Dest;
}
string RightString(BX_String, CX_Length)
{
// Returns the Right CX characters of BX_String
string Dest;
PUSH CX; // Save CX for later
Dest = BX; // Copy to new string
BX = StringLength(Dest); // Get the string length
POP CX; // Restore CX again
if(CX > BX) CX = BX; // Limit size of CX
CX = Dest + BX - CX; // Pointer to Address of start of new string
BX = Dest; // Point to start of Dest
while(S1[BX]) // while not end of string
{
if(BX .<. CX) // If Position < CX (Unsigned compare)
{
S1[BX] = 0; // Clear byte
Dest++; // Move string pointer forward
}
BX++; // Increment BX
}
if(Dest[0] == 0) Dest == StringHeapStartAddress + 2; // NULL string
return Dest;
}
string LeftString(BX_String, CX_Length)
{
// Returns the Left CX characters of BX_String
string Dest;
PUSH CX; Dest = BX; POP CX; // Copy to new string
BX = Dest; // Point to start of Dest
CX = CX + BX; // Point to character from where to start deleting
while(S1[BX]) // while not end of string
{
if(BX .>=. CX) S1[BX] = 0; // if Position >= CX then clear it (Unsigned compare)
BX++; // Increment BX
}
if(Dest[0] == 0) Dest == StringHeapStartAddress + 2; // NULL string
return Dest;
}
string CopyString(CX_SourceString)
{
// Copy a String.
// This is called by the compiler when you have the expression :-
// String1 = String2;
// so leave it to the compiler
string DestString;
string SourceString;
unsigned int Segment; // Initialised from Start()
preserve BX, DX, SI, BP, ES;
SourceString == CX_SourceString;
SI_DestString = AX;
ES = Segment;
AX = SS; // Used in if below
if(SI == SourceString && Segment == AX)
{
// If a string is copied from an address to the same address, then
// change the destination address to the NULL string, so that the
// string does not delete itself
SI_DestString = StringHeapStartAddress + 2;
DestString == SI;
}
CX = 0; BX = SourceString; // Put the Source String
while(E1[BX] != 0) { BX++; CX++; } // CX = length of Source String
// Check that destination is between heap limits
if(SI .<. StringHeapStartAddress || SI .>. StringHeapLastAddress)
{
// If the destination string is outside the string heap then make
// the destination string the NULL string. NB. this should never
// be neccessary but is included just in case someone writes a badly
// behaved program. You may want to call End(203) instead.
// End(203);
DestString == StringHeapStartAddress + 2; // Address of NULL string
}
while(S1[SI] != 0) { S1[SI] = 0; SI++; } // Clear the existing data
if(CX == 0) { DestString == StringHeapStartAddress + 2; return DestString; } // Return NULL string
while(S1[SI+1] == 0) SI++; // Search for start of next string
BP = DestString; // BP points to the start of the Destination String
BX = SI - BP; // Available bytes
if(BX < CX) // If not enough room
{ // Try moving backwards
while(!S1[BP-2] && !S1[BP-3]) BP--; // Search for end of last string
BX = SI - BP; // Available bytes
if(BX >= CX) // If enough room
{
BP = SI - CX; // Only take as much room as is needed
DestString == BP; // Update the Dest Address
}
else
{
// Store at the end of the Heap
DestString = RelocateString(CX);
BP = DestString;
}
}
// Copy the String in
SI = SourceString;
while(E1[SI] != 0) { S1[BP] = E1[SI]; SI++; BP++; }
return DestString; // Return Destination String Address
}
string AppendString(CX_CatString)
{
// Append a String.
// This is called by the compiler when you have the expression :-
// String1 = String1 + String2;
// so leave it to the compiler
string DestString;
string CatString;
preserve BX, DX, SI, BP;
CatString == CX_CatString;
BP = AX;
CX = StringLength(CX_CatString); // Get the Source String Length
// Check that between heap limits before appending string
if(BP .<. StringHeapStartAddress || BP .>. StringHeapLastAddress)
{
// The Destination String is not in the string heap so copy it into the heap
// before appending. This should not ever occur but is here just in case.
//cerr << "Not in String Heap\n";
//cerr << "BP = " << BP << "\n";
//cerr << "Start = " << StringHeapStartAddress << "\n";
SI = DestString;
BP = StringNextFreeAddress;
while(S1[BP-2] == 0) BP--; // Move back as far as possible
DestString == BP; // Update the Destination address
while(S1[SI] != 0) // For each Dest character
{
S1[BP] = S1[SI]; // Copy it to the end of the Heap
SI++; BP++;
}
BX = BP + CX; // Address of Terminate Character
S1[BX] = 0; // Terminate character for concatenated string
BX++; StringNextFreeAddress = BX; // New End of Heap Pointer
S1[BX] = '#'; // End of String Heap marker
}
else
{
// Destination is in the String Heap
while(S1[BP] != 0) BP++; // Search for the end of the string
BX = BP; // BX = End of Dest String pointer
while(S1[BP] == 0) BP++; // Search for the start of the next string
BP--; // Last available address
BX = BP - BX; // BX = number of spare bytes at end of Dest string
if(BX >= CX) // If enough room at end of Dest String
{ // to Concatenate other String
BP = BP - BX; // Point to end of Dest String before Concatenating
}
else
{
// There isn't enough room at the end so see if there would be enough room
// if the String was first moved backwards
SI = DestString; // Destination pointer
while(!S1[SI-2] && !S1[BP-3]) { SI--; BX++; } // Search for end of last string
if(BX >= CX) // If number of Spare Bytes >= Number required
{
// Move the String Backwards so that there is more room at the end
BP = DestString;
DestString == SI; // Update the Destination Address
while(S1[BP] != 0) { S1[SI] = S1[BP]; S1[BP] = 0; SI++; BP++; } // Move String back
BP = SI; // BP points to the end of the Dest string
}
else
{
// Move the Dest String to the end of the Heap
BP = StringLength(DestString);
DestString = RelocateString(BP+CX);
BP = BP + DestString;
}
}
}
// Concatenate the other String
SI = CatString; // Point to Source String
while(S1[SI] != 0) { S1[BP] = S1[SI]; SI++; BP++; }
if(DestString[0] == 0) DestString == StringHeapStartAddress + 2; // NULL String
return DestString;
}
int CompareString(AX, CX)
{
// Compare two strings
// This is called by the compiler when you have the expression :-
// if(String1 == String2) ... etc
// so leave it to the compiler
// Returns -1, 0, or 1 if Greater than, Equal or Less Than respectively
preserve SI, BP;
BP = AX;
SI = CX;
while(S1[SI] == S1[BP] && S1[SI] != 0) { SI++; BP++; } // Search for Mismatch
if(S1[SI] == 0 && S1[BP] == 0) return 0; // Strings are equal
if(S1[BP] > S1[SI]) return 1; // String1 > String 2
if(S1[BP] < S1[SI]) return -1; // String1 < String 2
}
int CompareNCharactersOfString(AX_String1, BX_String2, CX_Length)
{
// Compare first few characters of two strings
// Returns -1, 0, or 1 if Greater than, Equal or Less Than respectively
preserve SI, BP;
BP = AX_String1;
SI = BX_String2;
while(CX>0)
{
if(S1[BP] > S1[SI]) return 1;
if(S1[BP] < S1[SI]) return -1;
if(S1[BP] == 0 && S1[SI] == 0) return 0;
SI++;
BP++;
CX--;
}
return 0;
}
int StringLength(BX)
{
// Returns the String Length
AX = 0;
while(S1[BX] != 0) { BX++; AX++; }
return AX;
}
string StringUpperCase(BX)
{
// Converts a string to Upper Case
string DestString;
// Note that at the start of a String Function the return String in the String
// Function is set to the Destination String of the Calling Function. So if
// this Function was called with "NewString = StringUpperCase(OldString);" then
// DestString is now pointing to NewString, and BX is pointing to OldString.
// Copy the String to DestString if the Destination Address is different to the Source
if(DestString != BX) DestString = BX;
BX = DestString; // Let BX point to start of DestString
while(S1[BX] != 0)
{
if(S1[BX] >= 'a' && S1[BX] <= 'z') S1[BX] = S1[BX] - 32;
BX++;
}
return DestString;
}
string StringLowerCase(BX)
{
// Converts a string to Lower Case
string DestString;
// Copy the String to DestString if the Destination Address is different to the Source
if(DestString != BX) DestString = BX;
BX = DestString; // Let BX point to start of DestString
while(S1[BX] != 0)
{
if(S1[BX] >= 'A' && S1[BX] <= 'Z') S1[BX] = S1[BX] + 32;
BX++;
}
return DestString;
}
string SearchAndReplaceString(AX_String, BX_SearchString, CX_ReplaceString)
{
// Search one string for another string and replace it with another string
string String, SearchString, ReplaceString;
byte Match;
byte FoundAMatch; // Use this by calling program to detect if Match Found
int MatchPosition; // Use this by calling program to point to last Match
int StringLen;
int SearchStringLength;
int ReplaceStringLength;
int Offset;
preserve SI, BP, DX;
SearchString == BX;
ReplaceString == CX;
BP = String;
DL_FirstChar = S1[BX];
FoundAMatch = FALSE;
MatchPosition = -1;
while(S1[BP] != 0)
{
// Search for a match
if(S1[BP] == DL_FirstChar)
{
Match = TRUE;
PUSH BP;
SI = 0;
AL = SearchString[SI];
while(AL)
{
if(S1[BP] != AL) { Match = FALSE; break; }
SI++; BP++;
AL = SearchString[SI];
}
POP BP;
if(Match)
{
FoundAMatch = TRUE;
MatchPosition = BP - String;
StringLen = StringLength(String);
SearchStringLength = StringLength(SearchString);
ReplaceStringLength = StringLength(ReplaceString);
// If new string will be shorter then shuffle right hand side characters to the left
if(SearchStringLength > ReplaceStringLength)
{
Offset = SearchStringLength - ReplaceStringLength;
SI = BP + SearchStringLength;
PUSH BP;
BP = SI - Offset;
while(S1[SI] != 0) S1[BP++] = S1[SI++];
while(S1[BP]) S1[BP++] = 0;
POP BP; // Point back to Start of Match
StringLen = StringLen - Offset;
if(StringLen == 0) { String == StringHeapStartAddress + 2; return String; }
}
// If new string will be longer then shuffle right hand side characters to the right
if(SearchStringLength < ReplaceStringLength)
{
Offset = ReplaceStringLength - SearchStringLength;
// See if the string needs to be relocated
for(SI=StringLen+Offset; SI >= StringLen; SI--)
{
if(String[SI])
{
BP = BP - String; // Save Pointer Position
String = RelocateString(StringLen+Offset);
BP = BP + String; // Restore Pointer Position
break;
}
}
//SI = StringLen + Offset; String[SI] = 0;
SI = String + StringLen - 1;
CX = BP + SearchStringLength;
PUSH BP;
BP = SI + Offset;
while(SI .>=. CX) S1[BP--] = S1[SI--]; // Unsigned compare
POP BP; // Point back to Start of Match
StringLen = StringLen + Offset;
}
// Copy the Replace string in
SI = 0;
while(SI < ReplaceStringLength) S1[BP++] = ReplaceString[SI++];
BP--;
//PrintStringHeap();
}
}
BP++;
}
return String;
}
string RelocateString(CX_RequiredLength)
{
// Move a string to a place where there is sufficient space
// This is used by the other string functions
unsigned int HoleAddress;
string ThisString;
preserve BP;
BX = AX; // Address of string to be relocated
if(BX < StringHeapStartAddress) End(203); // Invalid String Address
// If there is enough room at the hole left by the last string then
// store it there
BP = HoleAddress; // Address of string hole
if(BP) // If a hole address has been stored
{
if(!S1[BP] && !S1[BP-1] && !S1[BP-2]) // The hole is still there
{
while(!S1[BP-3]) BP--; // Move to beginning of Hole
HoleAddress = BP; // New the Hole Address
while(!S1[BP+1] && !S1[BP+2] && !S1[BP+3]) BP++; // Find the end of the Hole
if(BP - HoleAddress > CX) // if enough room
{
//PUSH ALL; PrintChar(1, 'H'); POP ALL;
BP = HoleAddress;
HoleAddress = 0;
if(BX - 2 != StringHeapStartAddress) HoleAddress = BX; // Keep this hole for next time if is is not the NULL string
//if(BP .>. StringFirstAddress) { cerr << "BP = " << BP << "\n"; End(111); }
//if(BP .<. StringHeapStartAddress) { cerr << "BP = " << BP << "\n"; End(111); }
//if(BX .<. StringHeapStartAddress) { cerr << "BX = " << BX << "\n"; End(111); }
PUSH BP_OldHoleAddress; // Keep return address
while(S1[BX]) { S1[BP] = S1[BX]; S1[BX] = 0; BP++; BX++; } // Move String
POP BX_OldHoleAddress; // Restore return address
if(!HoleAddress) HoleAddress = BX + CX + 3;
ThisString == BX;
return ThisString;
}
}
else HoleAddress = 0;
}
//PUSH ALL; PrintChar(1, 'M'); POP ALL;
if(StringNextFreeAddress + CX .>=. StringHeapLastAddress) // If Heap Full
{
PUSH CX; // Keep the String length
TidyStringHeap(); // Tidy the String Heap to make room
POP CX; // Restore the String Length
BX = ThisString; // BX now equals the relocated ThisString
if(StringNextFreeAddress + CX .>=. StringHeapLastAddress)
{
// Fatal Error, String Heap Full !!!
// If the String heap is full then we cannot even terminate properly
// because that requires the String Heap, so the program terminates here
cerr << "String Heap Full\n";
AX = 4CC8h; INT 21h; // Terminate program with Error Code C8h
}
}
if(BX - 2 != StringHeapStartAddress) HoleAddress = BX + 1; // Keep the current address for future strings if not the NULL string
BP = StringNextFreeAddress; // Set the Address equal to the next free address
while(!S1[BP-1] && !S1[BP-2] && !S1[BP-3]) BP--; // Move back as far as possible
PUSH BP; // Keep the Destination Address
while(S1[BX]) { S1[BP] = S1[BX]; S1[BX] = 0; BP++; BX++; } // Move String
POP AX; // Return String Address
BP = AX + CX; // Address of Terminate Character
S1[BP++] = 0; // Terminate character string
S1[BP++] = 0; // Terminate character string
S1[BP] = '#'; // End of String Heap marker
StringNextFreeAddress = BP; // New End of Heap Pointer
ThisString == AX; return ThisString;
}
void ClearTemporaryString(BX)
{
// Used by compiler to clear Temporary strings
// Must not alter AX
while(S1[BX]) S1[BX++] = 0;
}
string PushString(AX)
{
// PUSH a string onto the string stack
// This is used by the "preserve" instruction to preserve a string
string PUSHString;
string TempString;
preserve BX, CX;
PUSHString == AX;
TempString = PUSHString; // Make a Duplicate
if(StringNextFreeAddress + 4 .>. StringFirstAddress)
{
TidyStringHeap();
if(StringNextFreeAddress + 4 .>. StringFirstAddress) End(202); // String Heap Full
}
StringFirstAddress = StringFirstAddress - 2; // Assign new String variable
S2[0] = StringFirstAddress; // Temporary ***
StringHeapLastAddress = StringHeapLastAddress - 2; // Change String Heap boundary
BX = StringFirstAddress;
S2[BX] = PUSHString;
// PUSHString is now allocated to S2[BX] so deallocate PUSHString
PUSHString == StringHeapStartAddress + 2; // Make PUSHString point to NULL String
return TempString;
}
string PopString()
{
// POP a string off the string stack
// This is used by the "preserve" instruction
// The string is restored to it's origional address so pointers to the
// string are still valid
string POPString;
preserve BX, CX;
POPString = ""; // Clear the old string
BX = StringFirstAddress;
POPString == S2[BX]; // Reassign PUSHed string to this string
StringFirstAddress = StringFirstAddress + 2; // Remove String variable
S2[0] = StringFirstAddress; // Temporary ***
StringHeapLastAddress = StringHeapLastAddress + 2; // Change String Heap boundary
return POPString;
}
void TidyStringHeap()
{
// Tidy the string heap so that there are no gaps
unsigned int StructureSegment[MAXSTRUCTURES];
byte Found;
preserve DI,SI,BP,DX,ES;
//cerr << "Tidying String Heap\n";
//LogFile << "Tidying String Heap\n";
// Check that all the string pointers are valid
for(DI=0; DI<MAXSTRUCTURES; DI++)
{
if(StructureSegment[DI])
{
ES = StructureSegment[DI];
for(SI=E2[0]; SI.<=.E2[2]; SI=SI+2) // for(SI=StringFirstAddress; SI.<=.StringLastAddress; SI=SI+2)
{
BP = E2[SI];
if(BP - 2 != StringHeapStartAddress) // If not the NULL String address
{
if(!S1[BP] || S1[BP-1]) // If there is no first character or the pointer points to the middle of a string
{
//PrintString(1, E2[SI]); cerr << " is invalid\n";
//PrintString(LogFile, E2[SI]); LogFile << " at address " << IntegerToHexString(SI) << " is invalid\n";
E2[SI] = StringHeapStartAddress + 2;
}
}
}
}
}
// Find the first string
BP = StringHeapStartAddress + 5;
while(S2[BP] != 0)
{
if(BP .>=. StringNextFreeAddress) return;
BP++;
}
DI = BP + 1;
while(S1[BP] == 0) BP++;
while(BP.<.StringNextFreeAddress)
{
Found = FALSE;
for(DX=0; DX<MAXSTRUCTURES; DX++)
{
if(StructureSegment[DX])
{
ES = StructureSegment[DX];
for(SI=E2[0]; SI.<=.E2[2]; SI=SI+2) // for(SI=StringFirstAddress; SI.<=.StringLastAddress; SI=SI+2)
{
if(E2[SI] == BP)
{
//PrintString(1, E2[SI]); cerr << " must move\n";
E2[SI] = DI;
Found = TRUE;
}
}
}
}
if(Found) while(S1[BP]) { S1[DI] = S1[BP]; S1[BP] = 0; DI++; BP++; }
else
{
#ifdef DEBUG
cerr << "Deleting '"; PrintString(1, BP); cerr << "'\n";
#endif
//LogFile << "Deleting '"; PrintString(LogFile, BP); LogFile << "'\n";
while(S1[BP]) S1[BP++] = 0;
//End(0);
}
DI++;
while(S1[BP] == 0) BP++;
}
StringNextFreeAddress = DI;
S1[DI] = '#';
RelocateString.HoleAddress = 0;
}
void PrintStringHeap()
{
// Print the String Heap
// Used for debugging only
preserve SI, DX;
SI = StringHeapStartAddress;
while(SI .<=. StringNextFreeAddress)
{
DL = S1[SI];
if(DL < ' ') DL = '.';
PutByte(cout, DL);
SI++;
}
PutByte(cout, 13);
PutByte(cout, 10);
}
void PrintScratchPad()
{
// Print the ScratchPad
// Used for debugging only
preserve ALL;
SI = ScratchPadAddress;
for(BX=0; BX<320h; BX++)
{
DL = S1[BX+SI];
if(DL < ' ') DL = '.';
if(DL > 127) DL = '.';
AH = 2; INT 21h;
}
DL = 13; INT 21h;
DL = 10; INT 21h;
}
string CharToString(AL)
{
string CharString;
BX = StringHeapStartAddress;
S1[BX++] = AL;
S1[BX] = 0;
CharString = StringHeapStartAddress;
return CharString;
}
string ByteToString(CL)
{
// Convert a byte to a string
string RetString;
CH = 0;
RetString = IntegerToString(CX);
return RetString;
}
string IntegerToString(CX)
{
// Convert an integer to a string
string RetString;
byte NegativeNumber;
preserve DX, DI;
AX = CX;
DI = ScratchPadAddress + 30;
S1[DI] = 0;
CX = 10;
if(AX == 0) { DI--; S1[DI] = '0'; }
NegativeNumber = 0;
if(AX < 0) { AX = - AX; NegativeNumber = 1; }
while(AX > 0)
{
DX = 0;
AX = DX:AX / CX; // DX = Remainder
DL = DL + 48;
DI--;
S1[DI] = DL;
}
if(NegativeNumber) { DI--; S1[DI] = '-'; }
RetString = DI; // Copy scratchpad into RetString
return RetString;
}
string ByteToHexString(CL_Word)
{
// Convert a byte to a HEX string
string DestString;
preserve DX;
DX_Word = CX_Word;
BX = ScratchPadAddress;
for(CL=4; CL>=0; CL=CL-4)
{
AX = ((DX >> CL) & 0xF) + 48;
if(AX > 57) AX = AX + 7;
S1[BX++] = AL;
}
S1[BX++] = 'h';
S1[BX] = 0;
DestString = ScratchPadAddress; // Copy string into DestString
return DestString;
}
string IntegerToHexString(CX_Word)
{
// Convert an integer to a HEX string
string DestString;
preserve DX;
DX_Word = CX_Word;
BX = ScratchPadAddress;
for(CL=12; CL>=0; CL=CL-4)
{
AX = ((DX >> CL) & 0xF) + 48;
if(AX > 57) AX = AX + 7;
S1[BX++] = AL;
}
S1[BX++] = 'h';
S1[BX] = 0;
DestString = ScratchPadAddress; // Copy string into DestString
return DestString;
}
string LongIntegerToHexString(ECX_Word)
{
// Convert a long integer to a HEX string
string DestString;
preserve EDX;
EDX_Word = ECX_Word;
BX = ScratchPadAddress;
for(CL=28; CL>=0; CL=CL-4)
{
EAX = ((EDX >> CL) & 0xF) + 48;
if(AX > 57) AX = AX + 7;
S1[BX++] = AL;
}
S1[BX++] = 'h';
S1[BX] = 0;
DestString = ScratchPadAddress; // Copy string into DestString
return DestString;
}
byte StringToByte(AX_StringAddress)
{
// Convert a string to a byte
// The string can be in integer or hex form
AX = StringToInteger(AX_StringAddress);
return AL;
}
int StringToInteger(string String)
{
// Convert a string to a signed integer
// The string can be in integer or hex form
int NumberIsValid;
int NumberIsNegative;
preserve DI, SI, DX;
NumberIsValid = FALSE;
DX = 0; // This is where the number will be placed
while(String[0] == ' ') String++; // Skip white space at start
SI = StringLength(String);
if(SI == 0) return 0;
SI--; while(String[SI] == ' ') SI--; // Skip white space at end
// See if type '?'
if(String[0] == ''' && String[2] == ''' && SI == 2)
{
NumberIsValid = TRUE;
DL = String[1];
}
// See if it is a Hex number ending with an "h"
else if(String[SI] == 'h')
{
for(DI=0; DI<SI; DI++)
{
NumberIsValid = TRUE;
if(String[DI] >= '0' && String[DI] <= '9') AL = String[DI] - 48;
else if(String[DI] >= 'A' && String[DI] <= 'F') AL = String[DI] - 55;
else if(String[DI] >= 'a' && String[DI] <= 'f') AL = String[DI] - 87;
else { NumberIsValid = FALSE; break; }
AH = 0;
DX = DX << 4;
DX = DX + AX;
} // end for
} // end if = "h"
// See if it is a Hex number starting with a "0x"
else if(String[0] == '0' && (String[1] == 'x' || String[1] == 'X'))
{
for(DI=2; DI<=SI; DI++)
{
NumberIsValid = TRUE;
if(String[DI] >= '0' && String[DI] <= '9') AL = String[DI] - 48;
else if(String[DI] >= 'A' && String[DI] <= 'F') AL = String[DI] - 55;
else if(String[DI] >= 'a' && String[DI] <= 'f') AL = String[DI] - 87;
else { NumberIsValid = FALSE; break; }
AH = 0;
DX = DX << 4;
DX = DX + AX;
} // end for
} // end if = "0x"
else
{
// Assume to be a Decimal number
NumberIsNegative = FALSE;
if(String[0] == '-') { NumberIsNegative = TRUE; String++; SI--; }
for(DI=0; DI<=SI; DI++)
{
NumberIsValid = TRUE;
if(String[DI] >= '0' && String[DI] <= '9')
{
AL = String[DI] - 48;
AH = 0;
DX = DX * 10;
DX = DX + AX;
}
else { NumberIsValid = FALSE; break; }
} // end for
if(NumberIsNegative) DX = -DX;
} // end if = Decimal Number
return DX;
}
long StringToLongInteger(string String)
{
// Convert a string to a signed long integer
// The string can be in integer or hex form
byte NumberIsValid;
int NumberIsNegative;
preserve DI, SI, EDX;
NumberIsValid = FALSE;
EDX = 0; // This is where the number will be placed
while(String[0] == ' ') String++; // Skip white space at start
SI = StringLength(String);
if(SI == 0) return 0;
SI--; while(String[SI] == ' ') SI--; // Skip white space at end
// See if type '?'
if(String[0] == ''' && String[2] == ''' && SI == 2)
{
NumberIsValid = TRUE;
DL = String[1];
}
// See if it is a Hex number ending with an "h"
else if(String[SI] == 'h')
{
for(DI=0; DI<SI; DI++)
{
NumberIsValid = TRUE;
EAX = 0;
if(String[DI] >= '0' && String[DI] <= '9') AL = String[DI] - 48;
else if(String[DI] >= 'A' && String[DI] <= 'F') AL = String[DI] - 55;
else if(String[DI] >= 'a' && String[DI] <= 'f') AL = String[DI] - 87;
else { NumberIsValid = FALSE; break; }
EDX = EDX << 4;
EDX = EDX + EAX;
} // end for
} // end if = "h"
// See if it is a Hex number starting with a "0x"
else if(String[0] == '0' && (String[1] == 'x' || String[1] == 'X'))
{
for(DI=2; DI<=SI; DI++)
{
NumberIsValid = TRUE;
EAX = 0;
if(String[DI] >= '0' && String[DI] <= '9') AL = String[DI] - 48;
else if(String[DI] >= 'A' && String[DI] <= 'F') AL = String[DI] - 55;
else if(String[DI] >= 'a' && String[DI] <= 'f') AL = String[DI] - 87;
else { NumberIsValid = FALSE; break; }
EDX = EDX << 4;
EDX = EDX + EAX;
} // end for
} // end if = "0x"
else
{
// Assume to be a Decimal number
NumberIsNegative = FALSE;
if(String[0] == '-') { NumberIsNegative = TRUE; String++; SI--; }
for(DI=0; DI<=SI; DI++)
{
NumberIsValid = TRUE;
if(String[DI] >= '0' && String[DI] <= '9')
{
EAX = 0;
AL = String[DI] - 48;
EDX = EDX * 10;
EDX = EDX + EAX;
}
else { NumberIsValid = FALSE; break; }
} // end for
if(NumberIsNegative) EDX = -EDX;
} // end if = Decimal Number
return EDX;
}